import java.util.Random;

public class LinkedList {

	private Node start;

	public LinkedList() {
		start = null;
	}

	public void insert(int x) {
		if (start == null) {
			start = new Node(x, start);
		} else {
			Node temp = start;

			while (temp.getNext() != null) {
				temp = temp.getNext();
			}
			Node newNode = new Node(x, null);
			temp.setNext(newNode);
		}
	}

	public void delete(int x) {
		Node previous = start;
		Node temp = start;

		while (temp.getData() != x) {
			if (temp.getNext() == null) {
				System.out.println("\nElement " + x + " not found !");
				break;
			}

			previous = temp;
			temp = temp.getNext();

		}
		if (temp == start) {
			start = start.getNext();
		} else {
			previous.setNext(temp);
		}
	}

	public void testdelete() {
		// del from an empty ll
		int i = 0;
		start = null;
		Random randomGenerator = new Random();
		System.out.print("testing to delete from a null linked list " + '\n');

		try {
			while (i < 100) {
				int randomInt = randomGenerator.nextInt(100);
				delete(randomInt);
				i++;
			}
		} catch (NullPointerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.print("fail to run remove for a null linked list!!!");
		}
		int j = 100;
		System.out.print("to remove a node with size 1 of ll" + '\n');
		while (j > 0) {
			start = null;
			int randomInt = randomGenerator.nextInt(100);
			insert(randomInt);
			System.out.print("the element at 1 pos without rm is : "
					+ randomInt + '\n');
			delete(randomInt);
			if (start == null) {
				System.out.print("the element at 1 pos is : null!" + '\n');
			} else {
				System.out.print("del failure!");
				return;
			}
			j--;
		}
		start = null;
		System.out.print("to remove a node with size > 1 of ll" + '\n');
		j=0;
		while (j < 100) {
			// fill ll
			int k = 100;
			while (k >= 0) {
				insert(k);
				k--;
			}
			int randomInt = randomGenerator.nextInt(100);
			delete(randomInt);
			System.out.print("the element rmed is : " + randomInt + '\n');
			while(start.getNext()!=null){
				if(start.getData()!=randomInt){
					start= start.getNext();
				}else{
					System.out.print("the element removal failure! " + '\n');
					return;
				}
			}
			
			
		j++;
		}

	}

	public void testinsert() {
		int i = 0;
		int j = 50;
		Random randomGenerator = new Random();
		System.out.print("testing a null linked list" + '\n');
		while (i < j) {
			int randomInt = randomGenerator.nextInt(100);
			insert(randomInt);
			System.out.print("inserting rand int = " + randomInt
					+ " insert value:" + start.getData() + '\n');
			if (start.getNext() != null) {
				System.out.print("failure at i = " + i);
				return;
			}
			delete(randomInt);
			i++;
		}
		i = 0;
		System.out.print("testing a non null linked list" + '\n');
		while (i < j) {
			int randomInt = randomGenerator.nextInt(100);
			randomInt = randomGenerator.nextInt(100);
			insert(randomInt);
			System.out.print("inserting rand int = " + randomInt
					+ " insert value:" + start.getData() + '\n');
			start = start.getNext();
			i++;
		}
		System.out
				.print("testing to add a node out of bound of a linked list" + '\n');
		while (i < j) {
			int randomInt = randomGenerator.nextInt(100);
			randomInt = randomGenerator.nextInt(100);
			start = start.getNext();
			insert(randomInt);
			System.out.print("inserting rand int = " + randomInt
					+ " insert value:" + start.getData() + '\n');
			start = start.getNext();
			i++;
		}
		System.out.print("all test passed!!!" + '\n');
		System.out
				.print("minor issue with the add, if adding an element out of bound "
						+ '\n' + "it does not throw any execptoins!");
	}
}